package com.ctsi.system.service;

import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.id.UUIDGenerator;
import com.ctsi.commons.util.response.Page;
import com.ctsi.framework.mybatis.support.MybatisGenericDao;
import com.ctsi.system.api.IDictionaryTreeData;
import com.ctsi.system.domain.DictionaryTreeData;
import com.ctsi.system.dto.DictTreeDataDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * DictionaryTreeData Service 类
 *
 * @author liuhx
 * @description DictionaryTreeData
 * @created Mon Sep 10 05:17:52 CST 2018
 */
@Service
public class DictionaryTreeDataService {
    private static final Logger logger = LoggerFactory.getLogger(DictionaryTreeDataService.class);
    @Autowired
    private MybatisGenericDao dao;

    public void setDao(MybatisGenericDao dao) {
        this.dao = dao;
    }

    /**
     * 根据id查询详情
     */
    public DictionaryTreeData selectDictTreeDataById(String id) {
        logger.debug("selectDictTreeDataById {}", id);
        return (DictionaryTreeData) dao.queryForObject(DictionaryTreeData.class.getName() + ".selectDictTreeDataById", id);
    }

    /**
     * 添加
     */
    @CacheEvict(value = {"dict-tree-data"})
    public void insertDictionaryTreeData(DictionaryTreeData data) {
        if (UtilValidate.isEmpty(data.getId())) {
            data.setId(UUIDGenerator.getId());
        }
        logger.debug("insert {}", data);
        dao.insert(data);
    }

    /**
     * 动态更新
     */
    @CacheEvict(value = {"dict-tree-data"})
    public int updateDictionaryTreeDataByPKSelective(DictionaryTreeData dictionaryTreeData) {
        logger.debug("updateByPrimaryKeySelective {}", dictionaryTreeData);
        return dao.update(DictionaryTreeData.class.getName() + ".updateByPrimaryKeySelective", dictionaryTreeData);
    }

    /**
     * 更新
     */
    @CacheEvict(value = {"dict-tree-data"})
    public int updateDictionaryTreeData(DictionaryTreeData dictionaryTreeData) {
        logger.debug("update {}", dictionaryTreeData);
        return dao.update(dictionaryTreeData);
    }


    public DictionaryTreeData editDictionaryTreeDataById(String id) {
        if (UtilValidate.isEmpty(id)) {
            return null;
        }
        logger.debug("editById {}", id);
        return (DictionaryTreeData) dao.queryForObject(DictionaryTreeData.class.getName() + ".edit", id);
    }

    /**
     * 根据ID查找 DictionaryTreeData对象
     */
    public DictionaryTreeData findDictionaryTreeDataById(String id) {
        if (UtilValidate.isEmpty(id)) {
            return null;
        }
        logger.debug("findById {}", id);
        return dao.get(DictionaryTreeData.class, id);
    }

    /**
     * 删除DictionaryTreeData对象
     */
    @CacheEvict(value = {"dict-tree-data"})
    public int removeDictionaryTreeData(String id) {
        if (UtilValidate.isNotEmpty(id)) {
            return dao.delete(DictionaryTreeData.class.getName() + ".delete", id);
        }
        return 0;
    }

    /**
     * 详细页查询
     */
    public Map<String, Object> findByDetail(String id) {
        return (Map<String, Object>) dao.queryForObject(DictionaryTreeData.class.getName() + ".findByDetail", id);
    }

    /**
     * 多条件查询结果
     */
    public Page<Map<String, Object>> findByMulitCondition(Map<String, Object> param, int start, int pageSize) {
        logger.debug("findByMulitCondition {}", param);
        if (pageSize < 0 || pageSize > 2000) {
            pageSize = Page.DEFAULT_PAGE_SIZE;
        }
        if (start != -1) {
            return dao.queryPage(DictionaryTreeData.class.getName() + ".selectMulitCondition", param, start, pageSize);
        } else {
            throw new RuntimeException("参数不正确 !!");
        }
    }

    /**
     * 多条件查询结果不分页
     */
    public List<DictionaryTreeData> find(Map<String, Object> map) {
        logger.debug("find {}", map);
        return (List<DictionaryTreeData>) dao.queryForList(DictionaryTreeData.class.getName() + ".selectByMap", map);
    }

    public DictionaryTreeData find(String type, String code) {
        if (UtilValidate.isEmpty(type) || UtilValidate.isEmpty(code)) {
            return null;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("typeId", type);
        params.put("code", code);
        return find(params).stream().findAny().get();
    }

    /**
     * 通过parentId和typeId获取字典树数据集合
     * 不查询已经删除的项目
     *
     * @param typeId
     * @param parentId
     * @return
     */
    @Cacheable(value = {"dict-tree-data"})
    public List<DictionaryTreeData> findDataByTypeAndParentId(String typeId, String parentId) {
        Map<String, Object> params = new HashMap<>(3);
        params.put("typeId", typeId);
        params.put("status", "normal");
        params.put("parentId", parentId);
        return find(params);
    }

    /**
     * 获取该类型的所有字典树数据,key为code
     *
     * @param type
     * @return
     */
    public List<DictTreeDataDTO> findTreeDataListByType(String type, Integer level) {
        if (UtilValidate.isEmpty(type)) {
            return Collections.emptyList();
        }
        Map<String, Object> params = new HashMap<>();
        params.put("typeId", type);
        List<DictTreeDataDTO> datas = (List<DictTreeDataDTO>) dao.queryForList(DictionaryTreeData.class.getName() + ".findDictTreeDTO", params);
        Collections.unmodifiableList(datas);
        return datas;
    }

    /**
     * 查询字典树链
     * 包括已经删除的项目
     *
     * @param type 字典树类型ID
     * @param code 字典项编码
     * @return
     */
    public List<IDictionaryTreeData> getTreeDataChain(String type, String code) {
        DictionaryTreeData dtd = this.find(type, code);
        List<IDictionaryTreeData> result = new ArrayList<>();
        if (dtd == null) {
            return Collections.unmodifiableList(result);
        }
        result.add(dtd);
        result = getDataChain(dtd.getParentId(), result);
        Collections.reverse(result);
        return Collections.unmodifiableList(result);
    }

    /**
     * 递归查询字典树
     *
     * @param parentId
     * @param dtds
     * @return
     */
    private List<IDictionaryTreeData> getDataChain(String parentId, List<IDictionaryTreeData> dtds) {
        if (!"root".equals(parentId)) {
            DictionaryTreeData dtd = this.findDictionaryTreeDataById(parentId);
            dtds.add(dtd);
            return getDataChain(dtd.getParentId(), dtds);
        }
        return dtds;
    }

    /**
     * 查询字典树的value
     * 此处应该查询全部项目，包括已删除的项目
     *
     * @param type
     * @param code
     * @return
     */
    public List<String> getTreeDataNameChain(String type, String code) {
        List<IDictionaryTreeData> result = getTreeDataChain(type, code);
        return Collections.unmodifiableList(result.stream().map(IDictionaryTreeData::getName).collect(Collectors.toList()));
    }

    /**
     * 判断字典树 是否是叶子节点
     *
     * @param id
     * @return
     */
    public boolean isLeaf(String id) {
        int result = (int) dao.queryForObject(DictionaryTreeData.class.getName() + ".isleaf", id);
        return result == 0;
    }

}
